package com.jf.cloud.service.sysmanager.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Created with IntelliJ IDEA.
 * User: LangK
 * Date: 2017/12/7
 * Time: 11:22
 * Description:日期工具
 */
public class DateUtil {

	/**
	 * 日志
	 */
	private static final Log log = LogFactory.getLog(DateUtil.class);

	/**
	 * 一小时毫秒数
	 */
	public static final long MILLISECONDS_OF_HOUR = 60 * 60 * 1000L;

	/**
	 * 一天毫秒数
	 */
	public static final long MILLISECONDS_OF_DAY = 24 * 60 * 60 * 1000L;

	/**
	 * 日期格式：yyyy-MM-dd
	 */
	public static final String YYYYMMDD_DASH = "yyyy-MM-dd";

	/**
	 * 日期时间格式：yyyy-MM-dd HH:mm:ss
	 */
	public static final String YYYYMMDD_DASH_HHMMSS_COLON = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 时间格式：HH:mm:ss
	 */
	public static final String HHMMSS_COLON = "HH:mm:ss";

	/**
	 * 日期格式：yyyyMMdd
	 */
	public static final String YYYYMMDD = "yyyyMMdd";

	/**
	 * 时间格式：HHmmss
	 */
	public static final String HHMMSS = "HHmmss";

	/**
	 * 日期时间格式：yyyyMMddHHmm （订单标号需要，年月日时分）
	 */
	public static final String YYYYMMDD_HHMM = "yyyyMMddHHmm";
	/**
	 * 日期时间格式：yyyyMMddHHmmss
	 */
	public static final String YYYYMMDD_HHMMSS = "yyyyMMddHHmmss";
	
	/**
	 * 日期时间格式：yyyyMMddHHmmssSSS 存在毫秒数
	 */
	public static final String YYYYMMDD_HHMMSS_SSS = "yyyyMMddHHmmssSSS";

	/**
	 * 日期格式：yyyy/MM/dd
	 */
	public static final String YYYYMMDD_SLASH = "yyyy/MM/dd";

	/**
	 * 日期格式：yyyy/MM/dd
	 */
	public static final String YYYYMMDD_SLASH_HHMMSS_COLON = "yyyy/MM/dd HH:mm:ss";
	
	/**
	 * 日期时间格式：yyyy-MM-dd 00:00:00
	 */
	public static final String YYYYMMDD_DASH_START_COLON = "yyyy-MM-dd 00:00:00";
	
	/**
	 * 日期时间格式：yyyy-MM-dd 23:59:59
	 */
	public static final String YYYYMMDD_DASH_END_COLON = "yyyy-MM-dd 23:59:59";
	
    /**
     * 判断是否是今天
     * @param date
     * @return
     */
    public static boolean isToday(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if(sdf.format(date).equals(sdf.format(new Date()))){
            return true;
        }
        return false;
    }

    public static boolean isHour(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("HH");
        if(sdf.format(date).equals(sdf.format(new Date()))){
            return true;
        }
        return false;

    }
	
	/**
	 * 获取当前日期/时间字符串 默认日期时间格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @return 当前日期/时间字符串
	 */
	public static String getCurrentDateTime() {
		return getCurrentDateTime(YYYYMMDD_DASH_HHMMSS_COLON);
	}

	/**
	 * 获取当前日期/时间字符串
	 * 
	 * @param pattern 日期/时间格式
	 * @return 当前日期/时间字符串
	 */
	public static String getCurrentDateTime(String pattern) {
		Calendar calendar = Calendar.getInstance();
		DateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取指定日期/时间字符串 默认日期时间格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @param field 日历字段
	 * @param offset 偏移量
	 * @return 日期/时间字符串
	 */
	public static String getDateTime(int field, int offset) {
		return getDateTime(YYYYMMDD_DASH_HHMMSS_COLON, field, offset);
	}

	/**
	 * 获取指定日期/时间字符串
	 * 
	 * @param pattern 日期/时间格式
	 * @param field 日历字段
	 * @param offset 偏移量
	 * @return 日期/时间字符串
	 */
	public static String getDateTime(String pattern, int field, int offset) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(field, offset);
		DateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取指定日期/时间字符串
	 * 
	 * @param pattern 日期/时间格式
	 * @param field 日历字段
	 * @param offset 偏移量
	 * @return 日期/时间字符串
	 */
	public static Date getDate(int field, int offset) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(field, offset);
		return calendar.getTime();
	}

	/**
	 * 获取指定日期/时间字符串 默认日期时间格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @param field 日历字段
	 * @param offset 偏移量
	 * @param date 给定日期/时间
	 * @return 日期/时间字符串
	 */
	public static String getDateTime(int field, int offset, Date date) {
		return getDateTime(YYYYMMDD_DASH_HHMMSS_COLON, field, offset, date);
	}

	/**
	 * 获取指定日期/时间字符串
	 * 
	 * @param pattern 日期/时间格式
	 * @param field 日历字段
	 * @param offset 偏移量
	 * @param date 给定日期/时间
	 * @return 日期/时间字符串
	 */
	public static String getDateTime(String pattern, int field, int offset, Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(field, offset);
		DateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 格式化日期 默认日期时间格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @param date Date 日期
	 * @return 日期/时间字符串
	 */
	public static String format(Date date) {
		return format(date, YYYYMMDD_DASH_HHMMSS_COLON);
	}

	/**
	 * 格式化日期
	 * 
	 * @param date Date 日期
	 * @param pattern 日期/时间格式
	 * @return 日期/时间字符串
	 */
	public static String format(Date date, String pattern) {
		String result = null;
		if (date != null) {
			DateFormat dateFormat = new SimpleDateFormat(pattern);
			result = dateFormat.format(date);
		}
		return result;
	}
	
	/**
	 * 获取默认日期时间
	 * 
	 * @return 日期
	 */
	public static Date getDate() {
		Date date = new Date();
		Calendar calendar = convert(date);
		return calendar.getTime();
	}

	/**
	 * 解析日期 默认日期时间格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @param source 日期字符串
	 * @return 日期
	 */
	public static Date parse(String source) {
		return parse(source, YYYYMMDD_DASH_HHMMSS_COLON);
	}


	/**
	 * 解析日期
	 * 
	 * @param source 日期字符串
	 * @param pattern 日期/时间格式
	 * @return 日期
	 */
	public static Date parse(String source, String pattern) {
		Date date = null;
		try {
			if (source != null && source.length() > 0) {
				DateFormat dateFormat = new SimpleDateFormat(pattern);
				date = dateFormat.parse(source);
			}
		} catch (ParseException e) {
			log.info("解析日期出错：", e);
			throw new RuntimeException("解析日期出错：", e);
		}

		return date;
	}

	/**
	 * 返回指定年数位移后的日期
	 */
	public static Date yearOffset(Date date, int offset) {
		return offsetDate(date, Calendar.YEAR, offset);
	}

	/**
	 * 返回指定月数位移后的日期
	 */
	public static Date monthOffset(Date date, int offset) {
		return offsetDate(date, Calendar.MONTH, offset);
	}

	/**
	 * 返回指定天数位移后的日期
	 */
	public static Date dayOffset(Date date, int offset) {
		return offsetDate(date, Calendar.DATE, offset);
	}

	/**
	 * 返回指定分钟位移后 时间
	 * 
	 */
	public static Date mintsOffset(Date date, int offset) {
		return offsetDate(date,  Calendar.MINUTE, offset);
	}
	
	/**
	 * 返回指定日期相应位移后的日期
	 * 
	 * @param date 参考日期
	 * @param field 位移单位，见 {@link Calendar}
	 * @param offset 位移数量，正数表示之后的时间，负数表示之前的时间
	 * @return 位移后的日期
	 */
	public static Date offsetDate(Date date, int field, int offset) {
		Calendar calendar = convert(date);
		calendar.add(field, offset);
		return calendar.getTime();
	}

	/**
	 * 返回当月第一天的日期
	 */
	public static Date getFirstDayOfMonth(Date date) {
		Calendar calendar = convert(date);
		calendar.set(Calendar.DATE, calendar.getMinimum(Calendar.DATE));
		return calendar.getTime();
	}

	/**
	 * 返回当月最后一天的日期
	 */
	public static Date getLastDayOfMonth(Date date) {
		Calendar calendar = convert(date);
		calendar.set(Calendar.DATE, calendar.getMaximum(Calendar.DATE));
		return calendar.getTime();
	}
	
	/**
	 * 返回本周星期一的日期
	 */
	public static String getFirstDayOfWeek(Date date) {
		Calendar calendar = convert(date);
		calendar.set(Calendar.DAY_OF_WEEK, calendar.getMinimum(Calendar.DAY_OF_WEEK));
		return DateUtil.getDateTime(DateUtil.YYYYMMDD_DASH, Calendar.DAY_OF_WEEK, 1, calendar.getTime());
	}
	
	/**
	 * 返回本周星期日的日期
	 */
	public static String getLastDayOfWeek(Date date) {
		Calendar calendar = convert(date);
		calendar.set(Calendar.DAY_OF_WEEK, calendar.getMaximum(Calendar.DAY_OF_WEEK));
		return DateUtil.getDateTime(DateUtil.YYYYMMDD_DASH, Calendar.DAY_OF_WEEK, 1, calendar.getTime());
	}

	/**
	 * 得到年份列表，一直到当前年
	 */
	public static List<String> getYearList(int fromYear) {
		List<String> yearList = new ArrayList<String>();

		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		int thisYear = cal.get(Calendar.YEAR);

		while (fromYear <= thisYear) {
			yearList.add(String.valueOf(fromYear));
			fromYear++;
		}
		return yearList;
	}

	/**
	 * 求时间差（天）
	 */
	public static long getDays(Date date, Date now) {
		long l = now.getTime() - date.getTime();

		return l / (24 * 60 * 60 * 1000);
	}

	/**
	 * 根据时间获取时间段
	 */
	public static String getPeriod(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(date.getTime());
		int hour = c.get(Calendar.HOUR_OF_DAY);
		return hour + ":00 - " + (hour + 1) + ":00";
	}

	/**
	 * 将时间计算成 天 、 小时 、 分 、 秒 、 毫秒
	 * 
	 * @param timeMillis
	 * @return
	 */
	public static String timeMillisToString(long timeMillis) {
		StringBuffer result = new StringBuffer();
		long days = timeMillis / (1000 * 60 * 60 * 24);
		long hours = (timeMillis % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
		long minutes = (timeMillis % (1000 * 60 * 60)) / (1000 * 60);
		long seconds = (timeMillis % (1000 * 60)) / 1000;
		long millisSeconds = timeMillis % 1000;
		result.append(days);
		result.append(" 天 ");
		result.append(hours);
		result.append(" 小时 ");
		result.append(minutes);
		result.append(" 分 ");
		result.append(seconds);
		result.append(" 秒 ");
		result.append(millisSeconds);
		result.append(" 毫秒 ");
		return result.toString();
	}

	/**
	 * 返回年份
	 * 
	 * @param date 日期
	 * @return 返回年份
	 */
	public static int getYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 * 返回月份
	 * 
	 * @param date 日期
	 * @return 返回月份
	 */
	public static int getMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH) + 1;
	}

	/**
	 * 返回日份
	 * 
	 * @param date 日期
	 * @return 返回日份
	 */
	public static int getDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 返回小时
	 * 
	 * @param date 日期
	 * @return 返回小时
	 */
	public static int getHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 返回分钟
	 * 
	 * @param date 日期
	 * @return 返回分钟
	 */
	public static int getMinute(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}

	/**
	 * 返回秒钟
	 * 
	 * @param date 日期
	 * @return 返回秒钟
	 */
	public static int getSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}

	/**
	 * 返回毫秒
	 * 
	 * @param date 日期
	 * @return 返回毫秒
	 */
	public static long getMillis(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.getTimeInMillis();
	}

	/**
	 * 日期相加
	 * 
	 * @param date Date 日期
	 * @param n 天数
	 * @return 返回相加后的日期
	 */
	public static Date addDate(Date date, int n) {
		Calendar calendar = convert(date);
		calendar.add(Calendar.DAY_OF_MONTH, n);
		return calendar.getTime();
	}

	/**
	 * 两日期相减
	 * 
	 * @param date1 日期
	 * @param date2 日期
	 * @return 天数
	 */
	public static int diffDate(Date date1, Date date2) {
		return (int) ((getMillis(date1) - getMillis(date2)) / MILLISECONDS_OF_DAY);
	}
	
	/**
	 * 两日期相减
	 * 
	 * @param date1 日期
	 * @param date2 日期
	 * @return 分钟
	 */
	public static Long diffMin(Date date1, Date date2) {
		long l=date1.getTime()-date2.getTime();// 获取与当前时间的时间差
	    long min=l/(60*1000);// 精确到分钟    
	    return min;
	}
	
	/**
	 * 两日期相减
	 * 
	 * @param date1 日期
	 * @param date2 日期
	 * @return date1 - date2  	单位：秒
	 */
	public static Long diffSecond(Date date1, Date date2) {
		long l = date1.getTime() - date2.getTime(); // 获取与当前时间的时间差
		long second = l / 1000; // 精确到秒    
		return Math.abs(second);
	}
	
	/**
	 * 两日期相减
	 * 
	 * @param date1 日期 yyyy-MM-dd HH:mm:ss
	 * @param date2 日期 yyyy-MM-dd HH:mm:ss
	 * @return 精确到秒
	 */
	public static String diffSecond(String date1, String date2) {
		SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String timeBetween = "";
        long between = 0;
		try {
             java.util.Date end = dfs.parse(date1);
             java.util.Date begin = dfs.parse(date2);
             between = (end.getTime() - begin.getTime());// 得到两者的秒数
        } catch (Exception ex) {
             ex.printStackTrace();
        }
		long day = between / (24 * 60 * 60 * 1000);
		if (day != new Long(0)) {
			timeBetween += day + "天";
		}
        long hour = (between / (60 * 60 * 1000) - day * 24);
        if (hour != new Long(0)) {
			timeBetween += hour + "小时";
		}
        long min = ((between / (60 * 1000)) - day * 24 * 60 - hour * 60);
        if (min != new Long(0)) {
			timeBetween += min + "分";
		}
        long s = (between / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        if (s != new Long(0)) {
			timeBetween += s + "秒";
		}
        
        return timeBetween;
	}

	/**
	 * 将日期转换为日历
	 * 
	 * @author 朱建文 创建时间：2017年12月22日 下午1:24:15
	 */
	private static Calendar convert(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	/**
	 * 格式化 日期字符串
	 */
	public static String setFormartValue(String dateStr) {
		if (StringUtil.isNotEmpty(dateStr)) {
			Date date = parse(dateStr);
			return format(date);
		}
		return "";
	}
	
	/**
	 * 时间转时间戳 
	 * 
	 * @author 朱建文 创建时间：2017年12月22日 下午1:24:01
	 */
	public static long dateTimeToTimestamp(String dateStr){
		long timeStamp = 0;
	 	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	Date date;
		try {
			date = format.parse(dateStr);
			timeStamp = date.getTime()/1000;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return timeStamp;
	}

	/**
	* 计算两个日期间的小时
	* 
	* @param fromDate 起始日期
	* @param toDate 结束日期
	* @return long
	*/
	public static long dateDiff(String fromDate, String toDate){
		long hours = 0;
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date from;
		Date to;
		try {
			from = df.parse(fromDate);
			to = df.parse(toDate);
			hours = (from.getTime() - to.getTime())/MILLISECONDS_OF_HOUR;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return hours;
	}

	
	/**
	* 计算两个日期时间差 精确到分钟
	* 
	* @param fromDate 起始日期
	* @param toDate 结束日期
	* @return long
	*/
	public static long dateDiffMinute(String fromDate, String toDate){
		long minute = 0;
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date from;
		Date to;
		try {
			from = df.parse(fromDate);
			to = df.parse(toDate);
			minute = (from.getTime() - to.getTime())/(60*1000);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		 return minute;
	}
	
}
